package tw.idv.liuken.android.sip.rtp;

import java.util.Arrays;

/*
 * Modified from Android's AudioCodec.
 */
public class VideoCodec {
    /**
     * The RTP payload type of the encoding.
     */
    public final int type;

    /**
     * The encoding parameters to be used in the corresponding SDP attribute.
     */
    public final String rtpmap;

    /**
     * The format parameters to be used in the corresponding SDP attribute.
     */
    public final String fmtp;

    public static final VideoCodec H263 = new VideoCodec(34, "H263/90000", null);
    public static final VideoCodec H264 = new VideoCodec(103, "H264/90000", null);
    public static final VideoCodec MP4VES = new VideoCodec(99, "MP4V-ES/90000", null);
    private static final VideoCodec[] sCodecs = {H263, H264, MP4VES};

    private VideoCodec(int type, String rtpmap, String fmtp) {
        this.type = type;
        this.rtpmap = rtpmap;
        this.fmtp = fmtp;
    }

    /**
     * Returns system supported audio codecs.
     */
    public static VideoCodec[] getCodecs() {
        return Arrays.copyOf(sCodecs, sCodecs.length);
    }

    /**
     * Creates an VideoCodec according to the given configuration.
     *
     * @param type The payload type of the encoding defined in RTP/AVP.
     * @param rtpmap The encoding parameters specified in the corresponding SDP
     *     attribute, or null if it is not available.
     * @param fmtp The format parameters specified in the corresponding SDP
     *     attribute, or null if it is not available.
     * @return The configured VideoCodec or {@code null} if it is not supported.
     */
    public static VideoCodec getCodec(int type, String rtpmap, String fmtp) {
        if (type < 0 || type > 127) {
            return null;
        }

        VideoCodec hint = null;
        if (rtpmap != null) {
            String clue = rtpmap.trim().toUpperCase();
            for (VideoCodec codec : sCodecs) {
                if (clue.startsWith(codec.rtpmap)) {
                    String channels = clue.substring(codec.rtpmap.length());
                    if (channels.length() == 0 || channels.equals("/1")) {
                        hint = codec;
                    }
                    break;
                }
            }
        } else if (type < 96) {
            for (VideoCodec codec : sCodecs) {
                if (type == codec.type) {
                    hint = codec;
                    rtpmap = codec.rtpmap;
                    break;
                }
            }
        }

        if (hint == null) {
            return null;
        }
        
        return new VideoCodec(type, rtpmap, fmtp);
    }
}
